//    Copyright (C) 2013  <lugocreation@gmail.com>
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
package org.jpgolay.me.discount;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import org.jpgolay.me.customer.Customer;
import org.jpgolay.me.item.Item;
import org.jpgolay.me.persistence.ObjectCRUD;
import org.jpgolay.me.util.Parameter;

// Referenced classes of package org.jpgolay.me.discount:
//            Discount
public class DiscountRate {

    public DiscountRate(Parameter param) {
        msg = "";
        this.param = param;
        crud = new ObjectCRUD();
    }

    public BigDecimal getRate(Customer customer, Item item, BigDecimal quantity) {
        return search(customer, item, quantity);
    }

    public String getMsg() {
        return msg;
    }

    private BigDecimal search(Customer customer, Item item, BigDecimal quantity) {
        BigDecimal zero = new BigDecimal(0);
        BigDecimal rate = new BigDecimal(0);
        if (isItemDiscount(customer.getId(), item.getId())) {
            BigDecimal discountByItem = discount.getRemise().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity1 = discount.getQtUn().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem1 = discount.getRemiseQtUn().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity2 = discount.getQtDeux().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem2 = discount.getRemiseQtDeux().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity3 = discount.getQtTrois().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem3 = discount.getRemiseQtTrois().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            if (quantity.compareTo(quantity3) >= 0 && quantity3.compareTo(zero) != 0) {
                rate = discountByItem3.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem3;
            } else if (quantity.compareTo(quantity2) >= 0 && quantity2.compareTo(zero) != 0) {
                rate = discountByItem2.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem2;
            } else if (quantity.compareTo(quantity1) >= 0 && quantity1.compareTo(zero) != 0) {
                rate = discountByItem1.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem1;
            } else if (discountByItem.compareTo(zero) == -1) {
                rate = discountByItem;
            } else {
                rate = discountByItem.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem;
            }
            msg = "Remise sur Article : " + rate.toString() + "% ";
        } else if (isItemFamilyDiscount(customer.getId(), item.getFamillesArticlesId())) {
            BigDecimal discountByItem = discount.getRemise().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity1 = discount.getQtUn().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem1 = discount.getRemiseQtUn().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity2 = discount.getQtDeux().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem2 = discount.getRemiseQtDeux().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal quantity3 = discount.getQtTrois().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            BigDecimal discountByItem3 = discount.getRemiseQtTrois().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            if (quantity.compareTo(quantity3) >= 0 && quantity3.compareTo(zero) != 0) {
                rate = discountByItem3.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem3;
            } else if (quantity.compareTo(quantity2) >= 0 && quantity2.compareTo(zero) != 0) {
                rate = discountByItem2.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem2;
            } else if (quantity.compareTo(quantity1) >= 0 && quantity1.compareTo(zero) != 0) {
                rate = discountByItem1.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem1;
            } else if (discountByItem.compareTo(zero) == -1) {
                rate = discountByItem;
            } else {
                rate = discountByItem.compareTo(item.getPromotion()) < 0 ? item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) : discountByItem;
            }
            msg = "Remise sur Famille d'Article : " + rate.toString() + "% ";
        } else {
            rate = item.getPromotion().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            msg = "Promotion : " + rate.toString() + "% ";
        }
        BigDecimal discountAdd;
        if (customer.getRemiseFidelite().compareTo(zero) != 0 && customer.getCotaFidelite().compareTo(zero) != 0 && customer.getTotalEncaisser().compareTo(customer.getCotaFidelite()) >= 0) {
            discountAdd = customer.getRemiseFidelite().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            msg = msg + "(Remise fid\351lit\351 client : " + discountAdd.setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) + "%) ";
        } else {
            discountAdd = customer.getRemise().setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            msg = msg + "(Remise client : " + discountAdd.setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue()) + "%) ";
        }
        if (rate.compareTo(zero) == 0) {
            rate = discountAdd;
            msg = msg + "Remise appliqu\351e : " + rate.toString() + "% ";
        } else {
            rate = rate.add(discountAdd.subtract(rate.movePointLeft(2).multiply(discountAdd))).setScale(param.getMinimumDecimalNumber().intValue(), param.getRoundType().intValue());
            msg = msg + "Remise appliqu\351e : " + rate.toString() + "% ";
        }
        return rate;
    }

    private boolean isItemDiscount(String customerId, String itemId) {
        java.util.Collection c = crud.readAll(customerId, 48);
        if (c != null) {
            ArrayList itemDiscountList = new ArrayList(c);
            for (Iterator it = itemDiscountList.iterator(); it.hasNext();) {
                discount = (Discount) it.next();
                if (discount.getArticleId().equals(itemId)) {
                    return true;
                }
            }

            return false;
        } else {
            return false;
        }
    }

    private boolean isItemFamilyDiscount(String customerId, String itemFamilyId) {
        java.util.Collection c = crud.readAll(customerId, 49);
        if (c != null) {
            ArrayList itemFamilyDiscountList = new ArrayList(c);
            for (Iterator it = itemFamilyDiscountList.iterator(); it.hasNext();) {
                discount = (Discount) it.next();
                if (discount.getArticleId().equals(itemFamilyId)) {
                    return true;
                }
            }

            return false;
        } else {
            return false;
        }
    }
    private String msg;
    private ObjectCRUD crud;
    private Parameter param;
    private Discount discount;
}
